﻿using System;
using System.Collections.Generic;
using System.Linq; 
 
namespace Kernelx.Contexts.Defaults.Sequences
{
    using _Internals;
    using Kernelx.Contexts.Core;

    /// <summary>
    /// 
    /// </summary>
    /// <param name="context"></param>
    /// <param name="args"></param>
    /// <returns></returns>
    public delegate string GetMaxID(IWorkloadContext context, IDictionary<string, string> args);


    /// <summary>
    /// 
    /// </summary>
    public class SequeConfigure
    {
        private readonly Dictionary<string, string> _formats = new Dictionary<string, string>();
        private readonly Dictionary<string, GetMaxID> _getMaxIds = new Dictionary<string, GetMaxID>();

        private readonly IList<BaseBracket> _brackets = new List<BaseBracket>();

        internal SequeConfigure() { }

        /// <summary> 
        /// <para>内置-特殊规则 {seq:长度} 在<paramref name="format"/>当中必须唯一</para>
        /// <para>内置-特殊规则 {args:属性名@长度} 用于接收外部传入的args对象的值</para>
        /// <para>内置-普通规则  {date:格式化串} / {date-utc:格式化串}  普通规则可追加 @args 用于将当前规则生成的值合并到args对象中</para>
        /// </summary>
        /// <param name="target"></param> 
        /// <param name="format"> 由多个{name:formula}组成的序号生成模板</param>
        /// <param name="getMaxId"></param>
        /// <returns></returns>
        public SequeConfigure Register(string target, string format, GetMaxID getMaxId)
        {
            _formats[target] = format;
            _getMaxIds[target] = getMaxId;
            return this;
        }

        /// <summary>
        /// 追加{Name:formula}普通规则的自定义实现解析对象
        /// </summary>
        /// <param name="bracket"></param>
        /// <returns></returns>
        public SequeConfigure Register(BaseBracket bracket)
        {
            var name = bracket.Name;
            if (!string.IsNullOrEmpty(name) && !_brackets.Any(n => n.Name == name))
                _brackets.Add(bracket);
            else
                throw new ApplicationException($"bracket.Name值为空或已注册过了 {bracket.Name}");
            return this;
        }


        internal ISequeGenerator Create() => new SequeGenerator(_formats, _getMaxIds, _brackets);

    }
}
